﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CSharpWrapper
{
    internal class ConfShareDesktopWrapper : IConferenceSharedesktop
    {
        public delegate void OnDisconnectShareServerDelegate(int result);
        //public delegate void OnNotifySharerListDelegate(IntPtr sharer_vector, int size);

        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct ConfShareDesktopCallback
        {
            public OnDisconnectShareServerDelegate OnDisconnectShareServerDelegate_;
            //public OnNotifySharerListDelegate OnNotifySharerListDelegate_;
        }

        public void OnDisconnectShareServer(int result)
        {
            foreach (IConferenceSharedesktopObserver observer in observer_list_)
                observer.OnDisconnectShareServer(result);
        }

//         public void OnNotifySharerList(IntPtr sharer_vector, int size)
//         {
//             List<String> sharers = new List<string>();
//             for (int i = 0; i < size; i++)
//                 sharers.Add(Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(sharer_vector, i * 4)));
//             foreach (IConferenceSharedesktopObserver observer in observer_list_)
//                 observer.OnNotifySharerList(sharers);
//         }

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_set_callback")]
        private static extern void lm_conf_sharedesktop_set_callback(
	        IntPtr instance,
	        ref ConfShareDesktopCallback callback);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_CreateView")]
        private static extern int lm_conf_sharedesktop_CreateView(
	        IntPtr instance,
	        String strSharer,
	        IntPtr hParent, 
	        int crBkg,
            ref IntPtr hChildWnd);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_DestroyView")]
        private static extern int lm_conf_sharedesktop_DestroyView(
	        IntPtr instance,
	        String strSharer);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_SetDisplayMode")]
        private static extern int lm_conf_sharedesktop_SetDisplayMode(
	        IntPtr instance,
	        String strSharer,
	        int nMode);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_GetSharerListSize")]
        private static extern int lm_conf_sharedesktop_GetSharerListSize(
	        IntPtr instance,
	        ref int count);

//         [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_GetSharerList")]
//         private static extern int lm_conf_sharedesktop_GetSharerList(
// 	        IntPtr instance,
//             IntPtr listSharer, 
//             int size,
// 	        ref int count);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_GetScreenResolution")]
        private static extern int lm_conf_sharedesktop_GetScreenResolution(
	        IntPtr instance,
            ref int nWidth,
            ref int nHeight);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_GetRemoteResolution")]
        private static extern int lm_conf_sharedesktop_GetRemoteResolution(
	        IntPtr instance,
            ref int nWidth,
            ref int nHeight);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_sharedesktop_SetRemoteResolution")]
        private static extern int lm_conf_sharedesktop_SetRemoteResolution(
	        IntPtr instance, 
	        int nWidth,
	        int nHeight);

        private IntPtr c_instance_;
        private List<IConferenceSharedesktopObserver> observer_list_;
        private ConfShareDesktopCallback conf_sharedesktop_callback_;

        public ConfShareDesktopWrapper(IntPtr c_instance)
        {
            c_instance_ = c_instance;
            observer_list_ = new List<IConferenceSharedesktopObserver>();
            conf_sharedesktop_callback_ = new ConfShareDesktopCallback();
            conf_sharedesktop_callback_.OnDisconnectShareServerDelegate_ = new OnDisconnectShareServerDelegate(OnDisconnectShareServer);
            //conf_sharedesktop_callback_.OnNotifySharerListDelegate_ = new OnNotifySharerListDelegate(OnNotifySharerList);
            lm_conf_sharedesktop_set_callback(c_instance, ref conf_sharedesktop_callback_);
        }

        #region IConferenceSharedesktop 成员

        public int AddObserver(IConferenceSharedesktopObserver observer)
        {
            if (observer_list_.Contains(observer))
                return -1;
            observer_list_.Add(observer);
            return 0;
        }

        public int RemoveObserver(IConferenceSharedesktopObserver observer)
        {
            observer_list_.Remove(observer);
            return 0;
        }

        public int CreateView(string strSharer, IntPtr hParent,
            System.Drawing.Color crBkg, ref IntPtr hChildWnd)
        {
            return lm_conf_sharedesktop_CreateView(c_instance_, strSharer, hParent, crBkg.ToArgb(), ref hChildWnd);
        }

        public int DestroyView(string strSharer)
        {
            return lm_conf_sharedesktop_DestroyView(c_instance_, strSharer);
        }

        public int SetDisplayMode(string strSharer, LMShareDesktopDisplayModes nMode)
        {
            return lm_conf_sharedesktop_SetDisplayMode(c_instance_, strSharer, (int)nMode);
        }

//         public int GetSharerList(List<String> listSharer)
//         {
//             int count = 0;
//             lm_conf_sharedesktop_GetSharerListSize(c_instance_, ref count);
//             if (count == 0)
//                 return 0;
// 
//             IntPtr p = IntPtr.Zero;
//             p = Marshal.AllocHGlobal(Marshal.SizeOf(p) * count);
//             for (int i = 0; i < count; i++)
//             {
//                 IntPtr pp = ConfHelper.NativeMalloc(128);
//                 Marshal.WriteIntPtr(p, i * 4, pp);
//             }
//             int count2 = count;
//             int ret = lm_conf_sharedesktop_GetSharerList(c_instance_, p, 128, ref count2);
//             if (ret == 0)
//             {
//                 for (int i = 0; i < count2; i++)
//                 {
//                     IntPtr pp = Marshal.ReadIntPtr(p, i * 4);
//                     listSharer.Add(Marshal.PtrToStringAnsi(pp));
//                 }
//             }
//             for (int i = 0; i < count; i++)
//             {
//                 IntPtr pp = Marshal.ReadIntPtr(p, i * 4);
//                 ConfHelper.NativeFree(pp);
//             }
// 
//             Marshal.FreeHGlobal(p);
//             return ret;
//         }

        public int GetScreenResolution(ref int nWidth, ref int nHeight)
        {
            return lm_conf_sharedesktop_GetScreenResolution(c_instance_, ref nWidth, ref nHeight);
        }

        public int GetRemoteResolution(ref int nWidth, ref int nHeight)
        {
            return lm_conf_sharedesktop_GetRemoteResolution(c_instance_, ref nWidth, ref nHeight);
        }

        public int SetRemoteResolution(int nWidth, int nHeight)
        {
            return lm_conf_sharedesktop_SetRemoteResolution(c_instance_, nWidth, nHeight);
        }

        #endregion
    }
}
